<template>
  <QueryForm :init-query="initQuery" v-model:value="queryForm" @submit="reloadTable">
    <template #default="{ queryForm }">
      <QueryItem
        :query-form="queryForm"
        :table-columns="tableColumns"
        v-bind="$attrs"
      ></QueryItem>
    </template>
  </QueryForm>
  <!-- <QueryForm :init-query="initQuery" v-model="queryForm" @submit="reloadTable" moreBtn="false">
    <template #default="{ queryForm }">
      <n-form-item label="所属系统">
        <n-select
          v-model:value="queryForm['resourceAppCode']"
          :options="appListOptions"
          clearable
          @change="reloadTable"
          style="width: 200px"
        />
      </n-form-item>
      <n-form-item label="功能名称">
        <n-input v-model:value="queryForm['searchKey']" clearable placeholder="请输入功能名称" />
      </n-form-item>
    </template>
  </QueryForm> -->
  <n-tree
    ref="treeRef"
    :checked-keys="checkedRows"
    class="slash-tree"
    style="height: calc(100% - 60px); overflow-y: scroll"
    block-line
    expand-on-dragenter
    default-expand-all
    selectable="true"
    :data="treeData"
    :node-props="nodeProps"
    :check-on-click="!readOnly"
    checkable
    virtual-scroll
    :render-label="renderLabel"
    key-field="id"
    check-strategy="all"
    :render-prefix="renderPrefix"
    :default-checked-keys="checkedRows"
    label-field="resourceName"
    :on-update:checked-keys="handleChecked"
  />
</template>

<script lang="ts">
  import { PropType, defineComponent, h, onBeforeMount, onMounted, reactive, ref } from 'vue';
  import {
    asyncApi,
    BasicTable,
    QueryForm,
    SysAppApi,
    QueryItem,
    SysResourceApi,
  } from 'slash-admin';
  import httpApi from '../httpApi';
  import { TreeOption } from 'naive-ui';

  interface ISysTbResourceResponse {
    [key: string]: any;
    parentPath?: string;
  }

  export default defineComponent({
    name: 'SelectResourceApiList',
    props: {
      checkedList: {
        type: Array as PropType<string[]>,
        default: undefined,
      },
      roleCode: {
        default: '',
      },
      readOnly: {
        type: Boolean,
        default: false,
      },
    },
    components: { BasicTable, QueryForm, QueryItem },
    setup(props, ctx) {
      const checkedRows = ref<string[]>([]);
      const treeRef = ref();
      const initQuery = {
        'resourceType-in': 'elm,menu',
      };
      const queryForm = ref<any>({
        ...initQuery,
      });
      const renderLabel = ({ option }: { option: TreeOption }) => {
        const label = option.resourceType != 'elm' ? '菜单' : '功能';
        return `[${label}]${option.resourceName}`;
      };
      const renderPrefix = (info: {
        option: Record<string, any> & TreeOption;
        checked?: boolean;
        selected?: boolean;
      }) => {
        const { option } = info;
        if (!option.children) {
          return null;
        }
        return h('i', {
          class: `${option.iconDefault} `,
          style: {
            color: `${option.enabled || option.children ? '' : '#0439f6'}`,
            marginRight: '0px',
          },
        });
      };
      const nodeProps = ({ option }: { option: TreeOption }) => {
        return {
          onClick() {
            ctx.emit('select', option);
          },
        };
      };
      const treeData = ref<any>();
      const getTreeNode = (
        tree: ISysTbResourceResponse[],
        id: string
      ): ISysTbResourceResponse | undefined => {
        for (let i = 0; i < tree.length; i++) {
          console.log('id', tree[i].id, id);
          if (tree[i].id === id) {
            return tree[i];
          }
          if (tree[i].children?.length) {
            return getTreeNode(tree[i].children as ISysTbResourceResponse[], id);
          }
        }
      };
      const loadDataTable = async (res) => {
        const msg = await SysResourceApi.selectSysTbResourceTreeList({
          searchKey: '',
          ...res,
          ...queryForm.value,
          'resourceType-in': 'elm,menu',
        });
        const handleNode = (trees: ISysTbResourceResponse[], parentPath: string) => {
          for (let i = 0; i < trees.length; i++) {
            trees[i].parentPath = parentPath
              ? `${parentPath}/${trees[i].fkParentId}`
              : trees[i].fkParentId;
            props.readOnly && (trees[i].checkboxDisabled = true);
            if (trees[i].children && trees[i].children?.length) {
              handleNode(
                trees[i].children as ISysTbResourceResponse[],
                trees[i].parentPath as string
              );
            }
          }
        };
        handleNode(msg.data, '');
        treeData.value = [
          {
            id: '0',
            resourceName: '全部权限',
            checkboxDisabled: props.readOnly,
            children: [...msg.data],
          },
        ];
      };
      // const appListOptions: ref<any> = asyncApi(async () => {
      //   const msg = await SysAppApi.doSelectPageList({ pageSize: 50 } as any);
      //   console.log(msg);
      //   const result = msg.data.map((it) => {
      //     return { value: it.appCode, label: it.appName };
      //   });
      //   console.log('返回数据', result);
      //   return result;
      // })();

      const doSubmit = async () => {
        let resourceIdList = [...checkedRows.value];
        console.log('aaa', resourceIdList);

        return httpApi.doUpdateRoleRelation({
          resourceIdList: [...resourceIdList],
          roleCode: props.roleCode,
        });
      };
      const updateCheckedKeys = (row) => {
        checkedRows.value[queryForm.resourceAppCode] = [...row];
        console.log(checkedRows.value);
      };

      function reloadTable() {
        setTimeout(() => {
          loadDataTable();
        }, 50);
      }

      const init = async () => {
        await loadDataTable();
        if (props.checkedList) {
          checkedRows.value = props.checkedList;
        } else {
          const msg = await httpApi.selectResourceIdListByRoleCode(props.roleCode);
          checkedRows.value = msg.data;
        }
        console.log('checkedRows', checkedRows.value);
      };

      const handleChecked = (
        keys: string[],
        options: ISysTbResourceResponse[],
        meta: { action: 'check' | 'uncheck'; node: any }
      ) => {
        let checkList = new Set(keys);
        // 触发节点
        const { action, node } = meta;
        console.log('action', action);

        // 子级跟随状态
        const handleChildren = (tree: ISysTbResourceResponse[], action: 'check' | 'uncheck') => {
          tree.forEach((item) => {
            if (action === 'check') {
              checkList.add(item.id);
            } else {
              checkList.delete(item.id);
            }
            if (item.children?.length) {
              handleChildren(item.children, action);
            }
          });
        };
        if (node.children?.length) {
          handleChildren(node.children, action);
        }
        // 父级
        const parents = node.parentPath?.split('/') || [];
        if (action === 'check') {
          parents.forEach((parent: string) => checkList.add(parent));
        } else {
          for (let i = parents.length - 1; i >= 0; i--) {
            const parentNode = getTreeNode(treeData.value, parents[i]);
            // 判断第一层子级是否全都未选中状态
            if (parentNode) {
              const isAllUncheck = !parentNode.children?.some((node) => {
                return checkList.has(node.id);
              });
              if (isAllUncheck) {
                checkList.delete(parentNode.id);
              }
            }
          }
        }
        checkedRows.value = Array.from(checkList);
      };
      onBeforeMount(() => {
        setTimeout(() => {
          init();
        }, 200);
      });
      return {
        renderLabel,
        queryForm,
        nodeProps,
        renderPrefix,
        loadDataTable,
        initQuery,
        checkedRows,
        reloadTable,
        doSubmit,
        treeData,
        // appListOptions,
        updateCheckedKeys,
        handleChecked,
        treeRef,
        tableColumns: [
          {
            title: '所属系统',
            key: 'resourceAppCode',
            searchProps: {
              type: 'select',
            },
          },
          {
            title: '功能名称',
            key: 'resourceName',
            searchType: 'like',
            searchProps: {
              type: 'text',
            },
          },
        ],
      };
    },
  });
</script>

<style lang="less" scoped></style>
